import { Markup } from "@antv/x6";
import { v4 as uuidV4 } from "uuid";

export default function generateNode(graph, nodeData) {
  let nodeClass = (nodeData.type || "model.start").split(".")[0];
  const { width, height, inArr, outArr } = nodeData;
  const portItems = [];
  // 添加 ports
  for (let i = 0, len = inArr.length; i < len; i++) {
    const { paramName, paramType } = inArr[i];
    portItems.push({
      id: uuidV4(),
      name: paramName,
      type: paramType,
      group: "in",
    });
  }
  for (let i = 0, len = outArr.length; i < len; i++) {
    const { paramName, paramType } = outArr[i];
    portItems.push({
      id: uuidV4(),
      name: paramName,
      type: paramType,
      group: "out",
    });
  }

  let maxLenPorts = Math.max(inArr.length, outArr.length); // 用来构造节点的高度
  let headerHeight = 20;
  let marginHeight = 10;
  let portHeight = 20;

  let resNode;

  if (nodeClass === "model") {
    resNode = graph.createNode({
      shape: "vue-shape",
      width: width || 150,
      height:
        height ||
        headerHeight + maxLenPorts * (marginHeight + portHeight) + marginHeight,
      data: { ...nodeData },
      portMarkup: [Markup.getForeignObjectMarkup()],
      ports: {
        groups: {
          in: {
            position: { name: "vue-model-left" },
            attrs: {
              fo: {
                width: 70,
                height: 20,
                x: 0,
                y: 0,
                magnet: "true",
              },
            },
            zIndex: 10,
          },
          out: {
            position: { name: "vue-model-right" },
            attrs: {
              fo: {
                width: 70,
                height: 20,
                x: -70,
                y: 0,
                magnet: "true",
              },
            },
            zIndex: 10,
          },
        },
        items: portItems,
      },
      component: "vue-model-node",
    });
  } else if (nodeClass === "port") {
    resNode = graph.createNode({
      shape: "vue-shape",
      width: width || 80,
      height: height || 30,
      data: { ...nodeData },
      ports: {
        groups: {
          in: {
            position: "left",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                strokeWidth: 1,
              },
            },
          },
          out: {
            position: "right",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                strokeWidth: 1,
              },
            },
          },
        },
        items: portItems,
      },
      component: "vue-port-node",
    });
  } else if (nodeClass === "subsystem") {
    resNode = graph.createNode({
      shape: "vue-shape",
      width: width || 150,
      height: height || 100,
      data: { ...nodeData },
      portMarkup: [Markup.getForeignObjectMarkup()],
      ports: {
        groups: {
          in: {
            position: { name: "vue-subsystem-left" },
            attrs: {
              fo: {
                width: 70,
                height: 20,
                x: 0,
                y: 0,
                magnet: "true",
              },
            },
            zIndex: 10,
          },
          out: {
            position: { name: "vue-subsystem-right" },
            attrs: {
              fo: {
                width: 70,
                height: 20,
                x: -70,
                y: 0,
                magnet: "true",
              },
            },
            zIndex: 10,
          },
        },
        items: portItems,
      },
      component: "vue-subsystem-node",
    });
  } else if (nodeClass === "math") {
    resNode = graph.createNode({
      shape: "vue-shape",
      width: width || 60,
      height: height || 60,
      data: { ...nodeData },
      ports: {
        groups: {
          in: {
            position: "left",
            label: {
              position: {
                name: "left",
              },
            },
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                strokeWidth: 1,
              },
              text: {
                fill: "white",
                fontSize: 12,
              },
            },
          },
          out: {
            position: "right",
            label: {
              position: {
                name: "right",
              },
            },
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                strokeWidth: 1,
              },
              text: {
                fill: "white",
                fontSize: 12,
              },
            },
          },
        },
        items: portItems,
      },
      component: "vue-meta-node",
    });
  } else if (nodeClass === "control") {
    resNode = graph.createNode({
      shape: "vue-shape",
      width: width || 150,
      height:
        height ||
        headerHeight + maxLenPorts * (marginHeight + portHeight) + marginHeight,
      data: { ...nodeData },
      portMarkup: [Markup.getForeignObjectMarkup()],
      ports: {
        groups: {
          in: {
            position: { name: "vue-model-left" },
            attrs: {
              fo: {
                width: 70,
                height: 20,
                x: 0,
                y: 0,
                magnet: "true",
              },
            },
            zIndex: 10,
          },
          out: {
            position: { name: "vue-model-right" },
            attrs: {
              fo: {
                width: 70,
                height: 20,
                x: -70,
                y: 0,
                magnet: "true",
              },
            },
            zIndex: 10,
          },
        },
        items: portItems,
      },
      component: "vue-model-node",
    });
  }

  return resNode;
}
